package com.njworkorder.Controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.njworkorder.Config.RunTConfig;
import com.njworkorder.DTO.ComponentsAddDto;
import com.njworkorder.DTO.DiseaseRegistrationAddDto;
import com.njworkorder.DTO.SelectDTO.SelectDRDto;
import com.njworkorder.DTO.SelectDTO.SelectDrWithIrDto;
import com.njworkorder.Entity.*;
import com.njworkorder.Entity.Dictionary;
import com.njworkorder.Handler.ScheduledTasks;
import com.njworkorder.Service.ComponentsService;
import com.njworkorder.Service.DiseaseRegistrationService;
import com.njworkorder.Service.DiseaseReportRecordService;
import com.njworkorder.Service.DiseaseService;
import com.njworkorder.Utils.FileOperation;
import com.njworkorder.Utils.Result;
import com.njworkorder.Utils.ResultUtil;
import com.njworkorder.VO.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.*;

@Tag(name = "病害登记", description = "病害登记相关接口")
@RestController
@RequestMapping("/diseaseRegistration")
public class DiseaseRegistrationController {


    @Autowired
    private ScheduledTasks scheduledTasks;

    private final DiseaseRegistrationService diseaseRegistrationService;
    private final DiseaseService diseaseService;
    private final RunTConfig runTConfig;
    private final ComponentsService componentsService;
    private final DiseaseReportRecordService diseaseReportRecordService;

    public DiseaseRegistrationController(DiseaseRegistrationService diseaseRegistrationService, RunTConfig runTConfig,
                                         ComponentsService componentsService,
                                         DiseaseService diseaseService,DiseaseReportRecordService diseaseReportRecordService) {
        this.diseaseRegistrationService = diseaseRegistrationService;
        this.runTConfig = runTConfig;
        this.componentsService = componentsService;
        this.diseaseService = diseaseService;
        this.diseaseReportRecordService = diseaseReportRecordService;
    }

    @Operation(summary = "上传文件")
    @PostMapping("/upload")
    public Result<Object> upload(@RequestPart("file") MultipartFile file) throws IOException {

        String filePath = FileOperation.fileSave(file, runTConfig.getUploadPath());

        if (!filePath.isEmpty()) {
            Map<String, String> map = new HashMap<>();
            map.put("url", runTConfig.getFileSavePath() + filePath);
            return ResultUtil.success(map);
        }
        return ResultUtil.fail("上传失败");
    }

    @Operation(summary = "添加病害登记信息")
    @PostMapping("/addInfo")
    public Result<String> addInfo(@RequestBody DiseaseRegistrationAddDto drDto,@RequestHeader("Create-Ap-Id") String createApId) {

        String id = UUID.randomUUID().toString();
        DiseaseRegistration DR = new DiseaseRegistration();
        BeanUtils.copyProperties(drDto, DR);
        DR.setId(id);
        DR.setCreateApId(createApId);

        saveComponentsList(id, false, drDto.getComponentsList());

        boolean b = diseaseRegistrationService.save(DR);
        if (b) {
            return ResultUtil.success("添加成功");
        }
        return ResultUtil.fail("添加失败");
    }

    private void saveComponentsList(String DrId, boolean isUpdate, List<ComponentsAddDto> componentsAddDtoList) {
        if (isUpdate) {
            LambdaQueryWrapper<Components> wrapper = new LambdaQueryWrapper<Components>()
                    .eq(Components::getDiseaseRegistrationId, DrId);
            componentsService.remove(wrapper);
        }
        if (componentsAddDtoList != null && !componentsAddDtoList.isEmpty()) {
            List<Components> componentsList = new ArrayList<>();
            Components components;
            for (ComponentsAddDto componentsAddDto : componentsAddDtoList) {
                components = new Components();
                BeanUtils.copyProperties(componentsAddDto, components);
                components.setDiseaseRegistrationId(DrId);
                componentsList.add(components);
            }
            componentsService.saveBatch(componentsList);
        }
    }

    @Operation(summary = "修改病害登记信息")
    @PostMapping("/updateInfo/{id}")
    public Result<String> updateInfo(@RequestBody DiseaseRegistrationAddDto drDto, @PathVariable("id") String id) {
        DiseaseRegistration dr = new DiseaseRegistration();
        BeanUtils.copyProperties(drDto, dr);
        dr.setId(id);

        saveComponentsList(id, true, drDto.getComponentsList());

        boolean b = diseaseRegistrationService.updateById(dr);
        if (b) {
            return ResultUtil.success("修改成功");
        }
        return ResultUtil.fail("修改失败");
    }

    @Operation(summary = "根据id删除病害登记信息")
    @GetMapping("/deleteById")
    public Result<String> deleteById(@RequestParam("id") String id) {
        boolean b = diseaseRegistrationService.removeById(id);

        LambdaQueryWrapper<Components> wrapper = new LambdaQueryWrapper<Components>()
                .eq(Components::getDiseaseRegistrationId, id);
        componentsService.remove(wrapper);

        if (b) {
            return ResultUtil.success("删除成功");
        }
        return ResultUtil.fail("删除失败");
    }

    @Operation(summary = "根据id查询病害登记信息")
    @GetMapping("/getById")
    public Result<DiseaseRegistrationListVo> getById(@RequestParam("id") String id) {

        MPJLambdaWrapper<Components> wrapper = componentsService.getMPJWrapper()
                .eq(Components::getDiseaseRegistrationId, id);
        List<ComponentsListVo> componentsListVos = componentsService.selectJoinList(ComponentsListVo.class, wrapper);

        MPJLambdaWrapper<DiseaseRegistration> wrapperDr = diseaseRegistrationService.getMPJWrapper().eq(DiseaseRegistration::getId, id);
        DiseaseRegistrationListVo diseaseRegistrationListVo = diseaseRegistrationService.selectJoinOne(DiseaseRegistrationListVo.class, wrapperDr);
        diseaseRegistrationListVo.setComponentsList(componentsListVos);

        return ResultUtil.success(diseaseRegistrationListVo);
    }


    @Operation(summary = "查询病害登记信息列表")
    @PostMapping("/getList")
    public Result<Page<DiseaseRegistrationListVo>> getList(@RequestBody SelectDRDto selectDRDto) {

        MPJLambdaWrapper<DiseaseRegistration> wrapper = diseaseRegistrationService.getMPJWrapper()

                .leftJoin(Dictionary.class, Dictionary::getId, DiseaseRegistration::getDirection,ext ->
                        ext.selectAs(Dictionary::getValusas, DiseaseRegistrationListVo::getDirectionValue))
                .leftJoin(Dictionary.class, Dictionary::getId, DiseaseRegistration::getLane,ext ->
                        ext.selectAs(Dictionary::getValusas, DiseaseRegistrationListVo::getLaneValue))

                .apply("1=1")
                .eq(selectDRDto.getInspectionRegistrationId() != null && !selectDRDto.getInspectionRegistrationId().isEmpty(), DiseaseRegistration::getInspectionRegistrationId, selectDRDto.getInspectionRegistrationId())
                .eq(selectDRDto.getDiseaseModule() != null && !selectDRDto.getDiseaseModule().isEmpty(), DiseaseRegistration::getDiseaseModule, selectDRDto.getDiseaseModule())
                .eq(selectDRDto.getDataSources() != null && !selectDRDto.getDataSources().isEmpty(), DiseaseRegistration::getDataSources, selectDRDto.getDataSources())
                .eq(selectDRDto.getRoute() != null && !selectDRDto.getRoute().isEmpty(), DiseaseRegistration::getRoute, selectDRDto.getRoute())
                .eq(selectDRDto.getPosition() != null && !selectDRDto.getPosition().isEmpty(), DiseaseRegistration::getPosition, selectDRDto.getPosition())
                .eq(selectDRDto.getStatus() != null && !selectDRDto.getStatus().isEmpty(), DiseaseRegistration::getStatus, selectDRDto.getStatus())
                .eq(selectDRDto.getUrgency() != null && !selectDRDto.getUrgency().isEmpty(), DiseaseRegistration::getUrgency, selectDRDto.getUrgency())
                .eq(selectDRDto.getDiseaseCategory() != null && !selectDRDto.getUrgency().isEmpty(), DiseaseRegistration::getDiseaseCategory, selectDRDto.getDiseaseCategory());

        Page<DiseaseRegistrationListVo> diseaseRegistrationListVoPage = diseaseRegistrationService.selectJoinListPage(new Page<>(selectDRDto.getPageIndex(), selectDRDto.getPageSize()), DiseaseRegistrationListVo.class, wrapper);
        return ResultUtil.success(diseaseRegistrationListVoPage);
    }


    @Operation(summary = "根据病害模块名称查询病害登记信息列表")
    @GetMapping("/getListByDiseaseModule")
    public Result<List<DiseaseRegistrationListVo>> getListByDiseaseModule(@RequestParam("DiseaseModuleName") String DiseaseModuleName) {

        MPJLambdaWrapper<DiseaseRegistration> wrapper = diseaseRegistrationService.getMPJWrapper()
                .apply("1=1").eq(DiseaseRegistration::getDiseaseModule, DiseaseModuleName).orderByDesc(DiseaseRegistration::getPublishTime);

        List<DiseaseRegistrationListVo> diseaseRegistrationListVos = diseaseRegistrationService.selectJoinList(DiseaseRegistrationListVo.class, wrapper);
        return ResultUtil.success(diseaseRegistrationListVos);
    }


    @Operation(summary = "根据病害模块查询病害登记信息和巡查信息列表")
    @PostMapping("/getDrAndIrList")
    public Result<Page<DrWithIrVo>> getDrAndIrList(@RequestBody SelectDrWithIrDto selectDrWithIrDto) {

        String diseaseId = "";
        if (selectDrWithIrDto.getDiseaseName() != null && StringUtils.isNotEmpty(selectDrWithIrDto.getDiseaseName())) {
            LambdaQueryWrapper<Disease> wrapper = new LambdaQueryWrapper<Disease>()
                    .select(Disease::getId)
                    .eq(Disease::getDiseaseName, selectDrWithIrDto.getDiseaseName());
            List<Disease> list = diseaseService.list(wrapper);
            if(!list.isEmpty()){
                diseaseId = list.getFirst().getId();
            }
        }

        MPJLambdaWrapper<DiseaseRegistration> wrapperDr = diseaseRegistrationService.getMPJWrapper()
                .selectAll(InspectionRegistration.class)
                .leftJoin(InspectionCar.class, InspectionCar::getId, InspectionRegistration::getInspectionCarId, ext ->
                        ext.selectAs(InspectionCar::getCarNum, DrWithIrVo::getCarNum))
                .leftJoin(Dictionary.class,Dictionary::getId,DiseaseRegistration::getDirection,ext ->
                        ext.selectAs(Dictionary::getValusas,DrWithIrVo::getDirectionName))
                .leftJoin(Dictionary.class,Dictionary::getId,DiseaseRegistration::getLane,ext ->
                        ext.selectAs(Dictionary::getValusas,DrWithIrVo::getLaneName))
                .ge(selectDrWithIrDto.getInspectionStartTime() != null,InspectionRegistration::getInspectionStartTime,selectDrWithIrDto.getInspectionStartTime())
                .le(selectDrWithIrDto.getInspectionEndTime() != null,InspectionRegistration::getInspectionEndTime,selectDrWithIrDto.getInspectionEndTime())
                .ge(StringUtils.isNotEmpty(selectDrWithIrDto.getStartPileNum()),DiseaseRegistration::getStartPileNum,selectDrWithIrDto.getStartPileNum())
                .le(StringUtils.isNotEmpty(selectDrWithIrDto.getEndPileNum()),DiseaseRegistration::getEndPileNum,selectDrWithIrDto.getEndPileNum())

                .eq(StringUtils.isNotEmpty(diseaseId),DiseaseRegistration::getDisease,diseaseId)
                .eq(selectDrWithIrDto.getUrgency() != null && StringUtils.isNotEmpty(selectDrWithIrDto.getUrgency()),DiseaseRegistration::getUrgency,selectDrWithIrDto.getUrgency())
                .eq(selectDrWithIrDto.getDiseaseModuleName() != null && !selectDrWithIrDto.getDiseaseModuleName().isEmpty(),DiseaseRegistration::getDiseaseModule, selectDrWithIrDto.getDiseaseModuleName())
                .eq(selectDrWithIrDto.getDataSources() != null && !selectDrWithIrDto.getDataSources().isEmpty(),DiseaseRegistration::getDataSources,selectDrWithIrDto.getDataSources())
                .eq(selectDrWithIrDto.getUrgency() != null && !selectDrWithIrDto.getUrgency().isEmpty(),DiseaseRegistration::getUrgency,selectDrWithIrDto.getUrgency())
                .orderByDesc(DiseaseRegistration::getPublishTime);

        Page<DrWithIrVo> drWithIrVoPage = diseaseRegistrationService.selectJoinListPage(new Page<>(selectDrWithIrDto.getPageIndex(), selectDrWithIrDto.getPageSize()), DrWithIrVo.class, wrapperDr);
        return ResultUtil.success(drWithIrVoPage);
    }



    @Operation(summary = "查询每个病害模块的病害登记数量")
    @GetMapping("/getEveryDiseaseModuleCount")
    public Result<List<Map<String, Object>>> getEveryDiseaseModuleCount() {

        QueryWrapper<DiseaseRegistration> wrapper = new QueryWrapper<DiseaseRegistration>()
                .select("disease_module as diseaseModuleName", "count(*) as count")
                .apply("1=1")
                .groupBy("disease_module");
        List<Map<String, Object>> maps = diseaseRegistrationService.listMaps(wrapper);

        return ResultUtil.success(maps);
    }


    @Operation(summary = "典型病害统计")
    @GetMapping("/getTypicalDiseaseStatistics")
    public Result<List<TDSVo>> getTypicalDiseaseStatistics(){

        MPJLambdaWrapper<DiseaseRegistration> wrapper = new MPJLambdaWrapper<DiseaseRegistration>()
                .selectAs(DiseaseRegistration::getDisease,TDSVo::getDiseaseId)
                .selectAs(Disease::getDiseaseName,TDSVo::getDiseaseName)
                .selectAs("count(*)",TDSVo::getDiseaseCount)
                .selectAs("ROUND((count(*) * 100.0 / (SELECT count(*) FROM disease_registration)), 2)",TDSVo::getRatio)
                .leftJoin(Disease.class,Disease::getId,DiseaseRegistration::getDisease)
                .apply("1=1")
                .groupBy(TDSVo::getDiseaseId);
        List<TDSVo> tdsVos = diseaseRegistrationService.selectJoinList(TDSVo.class, wrapper);

        return ResultUtil.success(tdsVos);
    }


    @Operation(summary = "获取病害上报统计")
    @GetMapping("/getDRStatistics")
    public Result<List<DRStatisticsVo>> getDRStatistics() {

        MPJLambdaWrapper<DiseaseRegistration> wrapper = new MPJLambdaWrapper<DiseaseRegistration>()
                .select(DiseaseRegistration::getId, DiseaseRegistration::getStartPileNum, DiseaseRegistration::getEndPileNum,DiseaseRegistration::getPublishTime)
                .selectAs(AdministrativePersonnel::getName,DRStatisticsVo::getApName)
                .selectAs(Workspace::getWorkspaceName,DRStatisticsVo::getWorkspaceName)

                .leftJoin(InspectionRegistration.class, InspectionRegistration::getId, DiseaseRegistration::getInspectionRegistrationId)
                .leftJoin(Workspace.class, Workspace::getId, InspectionRegistration::getWorkspaceId)
                .leftJoin(AdministrativePersonnel.class, AdministrativePersonnel::getId, DiseaseRegistration::getCreateApId)
                .apply("1=1").last("limit 4").orderByDesc(DiseaseRegistration::getPublishTime);

        List<DRStatisticsVo> drStatisticsVos = diseaseRegistrationService.selectJoinList(DRStatisticsVo.class, wrapper);
        return ResultUtil.success(drStatisticsVos);
    }


    @Operation(summary = "获取京沪病害上报统计")
    @GetMapping("/getDRRList")
    public Result<Page<DiseaseReportRecord>> getDRRList(@RequestParam("pageIndex") int pageIndex, @RequestParam("pageSize") int pageSize){
        LambdaQueryWrapper<DiseaseReportRecord>  wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(DiseaseReportRecord::getReporterTime);
        Page<DiseaseReportRecord> page = diseaseReportRecordService.page(new Page<>(pageIndex, pageSize),wrapper);
        return ResultUtil.success(page);
    }


    @Operation(summary = "综合管理-典型病害统计(京沪)")
    @GetMapping("/typicalDiseaseStatistics")
    public Result<Map<String,Object>> typicalDiseaseStatistics(){

        QueryWrapper<DiseaseReportRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("dis_name","count(*) as start_met");
        queryWrapper.groupBy("dis_name").orderByDesc("start_met");
        List<DiseaseReportRecord> list = diseaseReportRecordService.list(queryWrapper);


        List<Map<String,Object>> mapList = new ArrayList<>();
        Map<String,Object>  maps;

        // 计算总和
        double total = list.stream()
                .mapToDouble(DiseaseReportRecord::getStartMet)
                .sum();

        // 计算每个记录的占比
        for (DiseaseReportRecord record : list) {
            double proportion = record.getStartMet() / total;

            BigDecimal bd = new BigDecimal(proportion).setScale(2, RoundingMode.HALF_UP);
            // 如果需要乘以100并转为整数
            BigDecimal percentage = bd.multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP);
            //record.setStartKm(percentage.doubleValue());

            maps = new HashMap<>();
            maps.put("name",record.getDisName());
            maps.put("value",percentage.doubleValue());

            mapList.add(maps);
        }

        Map<String,Object> map = new HashMap<>();
        map.put("disTotal",total);
        map.put("diseaseClassification",mapList);

        return ResultUtil.success(map);
    }

    @Operation(summary = "获取京沪病害上报记录信息测试")
    @GetMapping("/qsyhxcOpenapiGetDisInfoTest")
    public void qsyhxcOpenapiGetDisInfoTest(@RequestParam(value = "sTime",required = false) String sTime) throws ParseException {
        scheduledTasks.scheduleTaskWithCronExpression3();
    }


}
